home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Game-Power
/
Amiga Game-Power.iso
/
pd mix ii
/
access
/
thai
/
say.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-05-20
|
6KB
|
308 lines
#include "quiz.h"
#include "devices/narrator.h"
#include "libraries/translator.h"
#include "trans.h"
#define MY_PITCH (2*DEFPITCH)
extern struct MsgPort * CreatePort();
extern struct IORequest * CreateExtIO();
extern LONG Translate ();
extern LONG OpenDevice ();
extern struct Library * OpenLibrary();
struct Library * TranslatorBase;
static struct MsgPort * writeport;
static struct narrator_rb * writeNarrator;
static UBYTE audChanMasks[4] = { 3,5,10,12 }; /* which channels to use */
static char outputstring[ 200 ];
init_speech ()
{
TranslatorBase = OpenLibrary ( "translator.library" , (LONG)2 );
if ( TranslatorBase == NULL )
return ( FALSE );
writeport = CreatePort ( (LONG)0 , (LONG)0 );
if ( writeport == NULL ) {
CloseLibrary ( TranslatorBase );
return ( FALSE );
}
writeNarrator = (struct narrator_rb *)
CreateExtIO ( writeport , (LONG) sizeof ( struct narrator_rb ) );
if ( writeNarrator == NULL ) {
DeletePort ( writeport );
CloseLibrary ( TranslatorBase );
return ( FALSE );
}
/* SET UP THE PARAMETERS FOR THE WRITE-MESSAGE TO THE NARRATOR DEVICE */
writeNarrator->ch_masks = (audChanMasks);
writeNarrator->nm_masks = sizeof ( audChanMasks );
writeNarrator->sex = MALE;
writeNarrator->mode = NATURALF0;
writeNarrator->pitch = MY_PITCH; /* raise pitch from default value */
writeNarrator->rate = DEFRATE;
writeNarrator->mouths = FALSE;
writeNarrator->message.io_Command = CMD_WRITE;
if ( OpenDevice ( "narrator.device" , (LONG)0 , writeNarrator , (LONG)0 )
!= 0 ) {
DeleteExtIO ( writeNarrator , (LONG) sizeof ( struct narrator_rb ) );
DeletePort ( writeport );
CloseLibrary ( TranslatorBase );
return ( FALSE );
}
return ( TRUE );
}
close_speech ()
{
/* terminate access to the device */
if ( writeNarrator != 0 )
CloseDevice ( writeNarrator );
/* now return system memory to the memory allocator */
if ( writeNarrator != 0 )
DeleteExtIO ( writeNarrator , (LONG) sizeof ( struct narrator_rb ) );
if ( writeport != 0 )
DeletePort ( writeport );
/* terminate access to the library */
if ( TranslatorBase != NULL )
CloseLibrary ( TranslatorBase );
}
speak_english ( str )
char *str;
{
Translate ( str , (LONG) strlen ( str ) , outputstring ,
(LONG) sizeof ( outputstring ) );
writeNarrator->message.io_Data = (APTR) outputstring;
writeNarrator->message.io_Length = strlen ( outputstring );
DoIO ( writeNarrator );
}
speak ( phonemes )
char *phonemes;
{
struct syllable syl;
while ( trans_syllable ( &phonemes , &syl ) )
say_syllable ( &syl );
}
static
say_syllable ( syl )
struct syllable *syl;
{
char *addstr;
addstr = "."; /* need a punctuation mark at the end */
switch ( syl->tone ) {
case HIGH_TONE :
writeNarrator->mode = ROBOTICF0;
writeNarrator->pitch = MY_PITCH + 30;
break;
case LOW_TONE :
writeNarrator->mode = ROBOTICF0;
writeNarrator->pitch = MY_PITCH - 30;
break;
default :
case MIDDLE_TONE :
writeNarrator->mode = ROBOTICF0;
writeNarrator->pitch = MY_PITCH;
break;
case RISING_TONE :
writeNarrator->mode = NATURALF0;
writeNarrator->pitch = MY_PITCH;
addstr = "?";
break;
case FALLING_TONE :
writeNarrator->mode = NATURALF0;
writeNarrator->pitch = MY_PITCH + 30;
break;
}
strcpy ( outputstring , syl->phonemes );
strcat ( outputstring , addstr );
writeNarrator->message.io_Data = (APTR) outputstring;
writeNarrator->message.io_Length = strlen ( outputstring );
writeNarrator->rate = DEFRATE / syl->duration;
DoIO ( writeNarrator );
}
static struct {
char user_phoneme[8];
char amiga_phoneme[8];
int duration;
} phoneme_table[] = {
{ "AA" , "AE" , 2 } ,
{ "AH" , "AH" , 2 } ,
{ "AI" , "AY" , 2 } ,
{ "AOU", "AW" , 2 } ,
{ "AO" , "AW" , 2 } ,
{ "AW" , "OH" , 2 } ,
{ "A" , "AH" , 1 } ,
{ "BP" , "B/H", 1 } ,
{ "B" , "B" , 1 } ,
{ "CH" , "CH" , 1 } ,
{ "DT" , "DX" , 1 } ,
{ "D" , "D" , 1 } ,
{ "EE" , "IY" , 2 } ,
{ "EH" , "EH" , 2 } ,
{ "ER" , "ER" , 2 } ,
{ "EUA", "ERAH" , 2 } ,
{ "EU" , "EHER" , 1 } , /* also EU bar duration 2 */
{ "F" , "F" , 1 } ,
{ "G" , "G" , 1 } ,
{ "H" , "/H" , 1 } ,
{ "IA" , "IHAH",1 } ,
{ "IH" , "IY" , 1 } ,
{ "IW" , "IHW", 1 } ,
{ "I" , "IH" , 1 } ,
{ "J" , "J" , 1 } ,
{ "KH" , "K" , 1 } ,
{ "K" , "K" , 1 } ,
{ "L" , "L" , 1 } ,
{ "M" , "M" , 1 } ,
{ "NG" , "NX" , 1 } ,
{ "N" , "N" , 1 } ,
{ "OA" , "AW" , 2 } ,
{ "OH" , "AA" , 2 } ,
{ "OO-AY" , "UHEY" , 1 } ,
{ "OO-A" , "UHA" , 1 } ,
{ "OO-Y" , "OY" , 2 } ,
{ "OOAY" , "UHEY" , 1 } ,
{ "OOA" , "UHA" , 1 } ,
{ "OOY" , "OY" , 2 } ,
{ "OO" , "UH" , 1 } ,
{ "OR" , "OH" , 1 } ,
{ "OY" , "OY" , 1 } ,
{ "P" , "P" , 1 } ,
{ "R" , "R" , 1 } ,
{ "S" , "S" , 1 } ,
{ "T" , "T" , 1 } ,
{ "UA" , "ERAH",1 } ,
{ "UH" , "AH" , 2 } ,
{ "UM" , "AHM", 1 } ,
{ "U" , "AH" , 1 } ,
{ "W" , "W" , 1 } ,
{ "Y" , "Y" , 1 } , /* y bar for long y */
{ "" , "" , 0 }
};
static
trans_syllable ( ip , syl )
char **ip;
struct syllable *syl;
{
int i;
syl->tone = MIDDLE_TONE;
syl->phonemes[0] = '\0';
syl->duration = 0;
while ( **ip == ' ' )
(*ip)++;
if ( **ip == '-' )
(*ip)++;
if ( **ip == '(' ) {
(*ip)++;
switch ( mklower ( *(*ip)++ ) ) {
case 'h' :
syl->tone = HIGH_TONE;
break;
case 'm' :
case 'c' :
case 'n' :
syl->tone = MIDDLE_TONE;
break;
case 'l' :
syl->tone = LOW_TONE;
break;
case 'r' :
syl->tone = RISING_TONE;
break;
case 'f' :
case 'd' :
syl->tone = FALLING_TONE;
break;
}
if ( **ip == ')' )
(*ip)++;
}
while ( **ip != '(' && **ip != ' ' && **ip != '\0' ) {
if ( **ip == '-' )
(*ip)++;
for ( i = 0; phoneme_table[i].user_phoneme[0] != '\0'; i++ ) {
if ( substr ( ip , phoneme_table[i].user_phoneme ) ) {
strcat ( syl->phonemes , phoneme_table[i].amiga_phoneme );
if ( syl->duration < phoneme_table[i].duration )
syl->duration = phoneme_table[i].duration;
break;
}
}
if ( phoneme_table[i].user_phoneme[0] == '\0' ) { /* not found */
return ( FALSE ); /* best that can be done */
}
if ( **ip == '!' ) {
(*ip)++;
syl->duration = ( syl->duration + 1 ) / 2;
}
}
return ( syl->phonemes[0] != '\0' );
}
static
substr ( buf , sub )
char **buf , *sub;
{
char *p;
p = *buf;
while ( *sub != '\0' ) {
if ( *p++ != *sub++ )
return ( FALSE );
}
*buf = p;
return ( TRUE );
}